using System;
using System.Collections.Generic;
using System.Text;

namespace WbsEditor
{
    class WbsPlausiChecker
    {
        public static void CheckWbs(WorkBreakdownStructure wbs, WbsTfsClient tfsClient)
        {
            CheckNodeRecursively(wbs, wbs.Root, tfsClient);
        }

        public static void CheckNodeRecursively(WorkBreakdownStructure wbs, WbsNode node, WbsTfsClient tfsClient)
        {
            CheckNode(wbs, node, tfsClient);
            foreach (WbsNode child in node.ChildNodes)
            {
                CheckNodeRecursively(wbs, child, tfsClient);
            }
        }

        private static string _lastTeamProject = "";
        private static string[] _iterationNodes = null;

        private static void CheckIterationNodes(WbsTfsClient tfsClient)
        {
            if (_lastTeamProject == tfsClient.TeamProject)
                return;
            _lastTeamProject = tfsClient.TeamProject;
            _iterationNodes = tfsClient.GetTeamProjectIterations();
        }

        public static bool IsIterationPathValid(WbsTfsClient tfsClient, string iterationPath)
        {
            CheckIterationNodes(tfsClient);
            string foundString = Array.Find<string>(_iterationNodes, delegate(string x)
            {
                return x.Equals(iterationPath);
            });
            return (null != foundString);
        }

        public static void CheckNode(WorkBreakdownStructure wbs, WbsNode node, WbsTfsClient tfsClient)
        {
            node.PlausiText = "";

            if (tfsClient.IsConnected)
            {
                if (!IsIterationPathValid(tfsClient, node.Iteration))
                {
                    node.PlausiText = "!The node's iteration is not found in the iteration list of the current project.";
                    return;
                }
            }

            if (node.IsPublished)
            {
                if (node.CompletedWorkInDays > 0.01f
                    && node.DisplayRemainingWorkInDays <= 0.01f
                    && node.State != "Closed")
                {
                    node.PlausiText = "Task has no remaining work but State is not 'Closed'.";
                    return;
                }

                if (node.DisplayRemainingWorkInDays > 0.01f
                    && node.State == "Closed")
                {
                    node.PlausiText = "Task has remaining work, but State is 'Closed'.";
                    return;
                }

                if (node.HasChildNodes && !node.IsRoot)
                {
                    node.PlausiText = "Published task has child nodes. Consider making it a leaf.";
                    return;
                }
            }

            if (!node.IsRoot && node.HasChildNodes)
            {
                if (node.RemainingWorkInDays > 0.01f
                    || node.CompletedWorkInDays > 0.01f)
                {
                    node.PlausiText = "Node has child nodes, yet also remaining and/or completed work. Consider removing work or making it a leaf.";
                    return;
                }

                if (node.ChildNodes.Count == 1)
                {
                    node.PlausiText = "Node has only one child. Consider eliminating this node.";
                    return;
                }
            }
        }
    }
}
